package org.xiaov.core.io;

import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 关于yaml文件的帮助类
 * </p>
 *
 * @author xiaovcloud
 * @since 2021/6/26 17:37
 */
public class YamlHelper {
    /**
     * 获取yaml中特定的值
     *
     * @param fileName
     * @param key
     * @return
     */
    public static String getValueWitName(String fileName, String key) {
        URL url = YamlHelper.class.getClassLoader().getResource(fileName);
        File file = null;
        if (url != null) {
            file = new File(url.getFile());
        }
        return getValueWithFile(file, key);
    }

    /**
     * 获取yaml中特定的值
     *
     * @param yamlFilePath
     * @param key
     * @return
     */
    public static String getValueWithPath(String yamlFilePath, String key) {
        File file = new File(yamlFilePath);
        return getValueWithFile(file, key);
    }


    /**
     * 获取yaml中特定的值
     *
     * @param yamlFile
     * @param key
     * @return
     */
    public static String getValueWithFile(File yamlFile, String key) {
        if (yamlFile != null) {
            Map<String, Object> map = yamlFile2map(yamlFile);
            if (map != null) {
                return map.get(key).toString();
            }
        }
        return null;
    }

    public static Map<String, Object> yamlName2map(String fileName) {
        URL url = YamlHelper.class.getClassLoader().getResource(fileName);
        File file = null;
        if (url != null) {
            file = new File(url.getFile());
        }
        return yamlFile2map(file);
    }

    /**
     * yaml转化成map
     *
     * @param yamlFilePath
     * @return
     */
    public static Map<String, Object> yamlPath2map(String yamlFilePath) {
        return yamlFile2map(new File(yamlFilePath));
    }

    /**
     * yaml转化成map
     *
     * @param yamlFile
     * @return
     */
    public static Map<String, Object> yamlFile2map(File yamlFile) {
        Map<String, Object> map = null;
        Yaml yaml = new Yaml();
        if (yamlFile != null && yamlFile.exists()) {
            try {
                map = yaml.load(new FileInputStream(yamlFile));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
        if (map == null) {
            return null;
        }
        //递归map对象将配置加载到conf对象中
        return loadRecursion(map, "", new HashMap<>(16));
    }


    /**
     * 递归解析map对象
     *
     * @param map  待解析的map
     * @param key  root的key
     * @param conf 返回的map
     * @return map
     */
    @SuppressWarnings("unchecked")
    private static Map<String, Object> loadRecursion(Map<String, Object> map, String key, Map<String, Object> conf) {
        map.forEach((k, v) -> {
            if (isParent(v)) {
                Map<String, Object> nextValue = (Map<String, Object>) v;
                loadRecursion(nextValue, (("".equals(key) ? "" : key + ".") + k), conf);
            } else {
                conf.put(key + "." + k, v);
            }
        });
        return conf;
    }

    /**
     * 判断是否还有子节点
     *
     * @param o
     * @return
     */
    private static boolean isParent(Object o) {
        if (!(o instanceof String
                || o instanceof Character
                || o instanceof Byte
                || o instanceof Boolean
                || o instanceof Long
        )) {
            try {
                Number n = (Number) o;
            } catch (Exception e) {
                return true;
            }
        }
        return false;
    }
}
